package com.zdsoft.config;

import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import com.zdsoft.intercept.AsynThreadException;
/***
 * 
 * <p>类描述:异步线程池</p>
 * @copyright www.zdsoft.cn
 * @author xingdaolin@msn.cn
 * @date  2016年12月1日
 * @version 1.0
 */
@EnableAsync
@Configuration
public class TaskExecutor implements AsyncConfigurer {
	@Autowired
	private ThreadProperty property;
	@Override
	public Executor getAsyncExecutor() {
		// TODO Auto-generated method stub
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		try {
			initThreadConf(executor);
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return executor;
	}

	@Override
	public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
		// TODO Auto-generated method stub
		return new AsynThreadException();
	}
	/***
	 * 获取cpus核数
	 * @return
	 */
	private int getSystemCpus(){
		int cpus = Runtime.getRuntime().availableProcessors();
		return cpus;
	}
	/**
	 * 初始化线程配置
	 * @param executor
	 */
	private void initThreadConf(ThreadPoolTaskExecutor executor) throws IllegalAccessException{
		if(this.property.isAuto()){//系统自动设置线程数
			int cpus = getSystemCpus();
			executor.setCorePoolSize(cpus);
			executor.setMaxPoolSize(cpus*2-1);
		}else{
			executor.setCorePoolSize(this.property.getCorePoolSize());
			executor.setMaxPoolSize(this.property.getMaxPoolSize());
		}
		executor.setQueueCapacity(this.property.getQueue());
		executor.setKeepAliveSeconds(this.property.getKeep());
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		executor.initialize();//必须调用此方法，实例化ExecutorService，否则会报线程池未实例化错误
	}
}
